
/**
	******************************************************************************
	* This file is part of the MicroPython project, http://micropython.org/
	* Copyright (C), 2021 -2022, 01studio Tech. Co., Ltd.http://bbs.01studio.org/
	* File Name 				 :	FT54x6.c
	* Author						 :	Folktale
	* Version 					 :	v1.0
	* date							 :	2021/3/18
	* Description 			 :	
	******************************************************************************
**/
#include "py/runtime.h"
#include "py/mphal.h"
#include "softtimer.h"

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>

#include "py/obj.h"

#include "pin.h"
#include "pin_static_af.h"
#include "mpu.h"
#include "systick.h"
#include "extint.h"
#include "py/mpthread.h"

#if (MICROPY_HW_FT54X6 && MICROPY_ENABLE_TFTLCD)

#include "ft54x6.h"
#include "modtftlcd.h"
#include "modtouch.h"
#include "tp_iic.h"

#ifndef MICROPY_HW_TP_RST
	#define MICROPY_HW_TP_RST 					(pin_C13)
	#define MICROPY_HW_TP_INT 					(pin_I11)
#endif

#define FT_CMD_WR 			0X70
#define FT_CMD_RD 			0X71

typedef struct _touch_ft_obj_t {
    mp_obj_base_t base;
} touch_ft_obj_t;

STATIC touch_ft_obj_t ft54x6_obj;

//----------------------------------------------------------------------
static void ft54xx_read_data(uint8_t reg,uint8_t *buf,uint8_t len)
{
	uint8_t i; 
 	TP_IIC_START();	
 	TP_IIC_Send_Byte(FT_CMD_WR);   	//发送写命令 	 
	TP_IIC_Wait_Ack(); 	 										  		   
 	TP_IIC_Send_Byte(reg);
	TP_IIC_Wait_Ack();  
 	TP_IIC_START();  	 	   
	TP_IIC_Send_Byte(FT_CMD_RD);
	TP_IIC_Wait_Ack();	   
	for(i=0;i<len;i++)
	{	   
    	buf[i]=TP_IIC_Read_Byte(i==(len-1)?0:1);
	} 
  TP_IIC_Stop();   
} 

STATIC void ft_Init(void)
{

	TP_IIC_Init();
	
	mp_hal_pin_config(MICROPY_HW_TP_RST, MP_HAL_PIN_MODE_OUTPUT,MP_HAL_PIN_PULL_UP, 0);
	mp_hal_pin_config(MICROPY_HW_TP_INT, MP_HAL_PIN_MODE_INPUT,MP_HAL_PIN_PULL_UP, 0);
	
	mp_hal_pin_high(MICROPY_HW_TP_RST);
	mp_hal_delay_ms(100) ;//10ms

	ft54xx_read_data(0xA1,tp_dev.id,2);

	//printf("tp_dev.id:%x%x\r\n",tp_dev.id[0],tp_dev.id[1]);
}
//===============================================================================

static uint16_t touch_w,touch_h;
void ft54x6_read_point(void)
{
    uint8_t touch_num = 0;
    uint8_t read_buf[7] = {0};
    uint16_t input_x = 0;
    uint16_t input_y = 0;
    int16_t input_w = 0;
		int8_t read_id = 0;
    static uint8_t pre_touch = 0;

	ft54xx_read_data(0x01, read_buf, 6);

    touch_num = read_buf[1] % 6; 

    if (pre_touch > touch_num){
     tp_touch_up(read_id);
    }
		if (touch_num == 0){
			pre_touch = touch_num;
			return;
    }

    if (touch_num){	
      switch (tp_dev.dir)
        {
          case 2:
			input_y = (uint16_t)(800-( ((read_buf[4] & 0x0F)<<8) + read_buf[5]));
			input_x = (uint16_t)(480-( ((read_buf[2] & 0x0F)<<8) + read_buf[3]));
          break;
          case 3:
			input_x = (uint16_t)(800-( ((read_buf[4] & 0x0F)<<8) + read_buf[5]));
			input_y = (uint16_t)( ((read_buf[2] & 0x0F)<<8) + read_buf[3]);
          break;
          case 4:
			input_y = (uint16_t)( ((read_buf[4] & 0x0F)<<8) + read_buf[5]);
			input_x = (uint16_t)( ((read_buf[2] & 0x0F)<<8) + read_buf[3]);
          break;
          default:
			input_x = (uint16_t)( ((read_buf[4] & 0x0F)<<8) + read_buf[5]);
			input_y = (uint16_t)(480 - (((read_buf[2] & 0x0F)<<8) + read_buf[3]));
          break;
        }

		if(input_x >= touch_w || input_y >= touch_h){
			return;
		}
		//printf("lcddev.dir:%d,x:%d,,y:%d\r\n",lcddev.dir,input_x,input_y);
       	tp_touch_down(read_id, input_x, input_y, input_w);
    }else if (pre_touch){
       tp_touch_up(read_id);
    }
    pre_touch = touch_num;
}
/**********************************************************************************************************/

//==========================================================================================
STATIC mp_obj_t touch_ft54xx_read(void)
{
	mp_obj_t tuple[3];
	ft54x6_read_point();
	if (tp_dev.sta&TP_PRES_DOWN) tuple[0] = mp_obj_new_int(0);
	else if(tp_dev.sta&TP_PRES_MOVE)	tuple[0] = mp_obj_new_int(1); 
	else 	tuple[0] = mp_obj_new_int(2); 
		
	tuple[1] = mp_obj_new_int(tp_dev.x[0]);
	tuple[2] = mp_obj_new_int(tp_dev.y[0]);
	return mp_obj_new_tuple(3, tuple);
}STATIC MP_DEFINE_CONST_FUN_OBJ_0(touch_ft54xx_read_obj, touch_ft54xx_read);
//------------------------------------------------------------------------------------------------------
STATIC mp_obj_t touch_ft54xx_scan(void)
{
	ft54x6_read_point();
	return mp_const_none;
}STATIC MP_DEFINE_CONST_FUN_OBJ_0(touch_ft54xx_scan_obj, touch_ft54xx_scan);


//-----------------------------------------------------------------------------------------------
STATIC void touch_ft54x6_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
	mp_printf(print,"TP ID:%s\r\n",tp_dev.id);
}
//------------------------------------------------------------------------------------------------------
STATIC mp_obj_t touch_tf54x6_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
	static const mp_arg_t allowed_args[] = {
			{ MP_QSTR_portrait, MP_ARG_INT, {.u_int = 1} },
	};
	
	mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
	mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
	
	
	// if(args[0].u_int != 0)
	{
		tp_dev.dir = args[0].u_int;
	}
	
	switch (tp_dev.dir)
	{
		case 2:
		touch_w=480;
		touch_h=800;
		break;
		case 3:
		touch_w=800;
		touch_h=480;
		break;
		case 4:
		touch_w=480;
		touch_h=800;
		break;
		case 1:
		touch_w=800;
		touch_h=480;
		break;
	}

	ft_Init();

	touch_is_init = 1;
	
	tp_dev.type = 1;
	ft54x6_obj.base.type = &touch_ft_type;
	return MP_OBJ_FROM_PTR(&touch_ft_type);
}

//===================================================================
STATIC const mp_rom_map_elem_t touch_tf54x6_locals_dict_table[] = {
	// instance methods
	{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&touch_ft54xx_read_obj) },
	{ MP_ROM_QSTR(MP_QSTR_tick_inc), MP_ROM_PTR(&touch_ft54xx_scan_obj) },
};

STATIC MP_DEFINE_CONST_DICT(touch_tf54x6_locals_dict, touch_tf54x6_locals_dict_table);

const mp_obj_type_t touch_ft_type = {
    { &mp_type_type },
    .name = MP_QSTR_FT5436,
    .print = touch_ft54x6_print,
    .make_new = touch_tf54x6_make_new,
    .locals_dict = (mp_obj_dict_t *)&touch_tf54x6_locals_dict,
};
#endif

/**********************************************************************************************************/
